package com.google.code.coma.loadbalancer.sd;


import com.google.code.coma.domain.Part;
import com.google.code.coma.domain.Type;
import com.google.code.coma.loadbalancer.entity.FactoryTypeAmount;

import java.util.ArrayList;
import java.util.List;

/**
 */
public class FactorySupplyDemandFactory {
    public static FactorySupplyDemand createSupplyDemand(String factoryId, List<Part> parts) {
        List<Part> cpuList = new ArrayList<Part>();
        List<Part> ramList = new ArrayList<Part>();
        List<Part> mainboardList = new ArrayList<Part>();

        for (Part part : parts) {
            if (part.getType().equals(Type.CPU)) {
                cpuList.add(part);
            } else if (part.getType().equals(Type.Mainboard)) {
                mainboardList.add(part);
            } else if (part.getType().equals(Type.RAM)) {
                ramList.add(part);
            }
        }

        return createSupplyDemand(factoryId, cpuList, Type.CPU, mainboardList, Type.Mainboard, ramList, Type.RAM);
    }

    private static FactorySupplyDemand createSupplyDemand(String factoryId, List<Part> p1List, Type p1Type, List<Part> p2List, Type p2Type, List<Part> p3List, Type p3Type) {
        if (factoryId == null || p1List == null || p2List == null || p3List == null || p1Type == null || p2Type == null || p3Type == null) {
            throw new IllegalArgumentException("No null values supported");
        }

        if (p1List.size() > p2List.size()) {
            return createSupplyDemand(factoryId, p2List, p2Type, p1List, p1Type, p3List, p3Type);
        }

        if (p2List.size() > p3List.size()) {
            return createSupplyDemand(factoryId, p1List, p1Type, p3List, p3Type, p2List, p2Type);
        }

        FactorySupplyDemand factorySupplyDemand = new FactorySupplyDemand();

        if (p3List.size() == 0) {
            factorySupplyDemand.getDemand().add(new FactoryTypeAmount(factoryId, Type.CPU, 1));
            factorySupplyDemand.getDemand().add(new FactoryTypeAmount(factoryId, Type.Mainboard, 1));
            factorySupplyDemand.getDemand().add(new FactoryTypeAmount(factoryId, Type.RAM, 1));

            return  factorySupplyDemand;
        }

        if (p2List.size() == p3List.size()) {
            factorySupplyDemand.getDemand().add(new FactoryTypeAmount(factoryId, p1Type, p2List.size() - p1List.size()));
            factorySupplyDemand.getSupply().add(new FactoryTypeAmount(factoryId, p2Type, p2List.size()));
            factorySupplyDemand.getSupply().add(new FactoryTypeAmount(factoryId, p3Type, p3List.size()));

            return factorySupplyDemand;
        }

        if (p3List.size() == 1) {
            return factorySupplyDemand;
        }

        factorySupplyDemand.getDemand().add(new FactoryTypeAmount(factoryId, p1Type, p2List.size() - p1List.size()));
        factorySupplyDemand.getSupply().add(new FactoryTypeAmount(factoryId, p3Type, p3List.size() - p2List.size()));

        return factorySupplyDemand;
    }
}
